import ROBOT_AVATAR from '@/assets/image/avatar_robo.png';
import POINTLOADING from '@/assets/image/pointloading.gif';
import USER_AVATAR from '@/assets/image/user_avatar.png';
import { extractKeyPoints, structuringWrite } from '@/services/ant-design-pro/dialog';
import { CommandType } from '@/services/models/conversation';
import { replaceN } from '@/utils/index';
import { LeftOutlined } from '@ant-design/icons';
import { Button, Input, message } from 'antd';
import { cloneDeep } from 'lodash';
import { nanoid } from 'nanoid';
import { stringify } from 'querystring';
import React, { useEffect, useRef, useState } from 'react';
import { connect, history } from 'umi';
import Demo from './com/Demo';
import General from './com/generalCon';
import Guide from './com/Guide';
import LookTip from './com/LookTip';
import SelectNum from './com/SelectNum';
import './index.less';
const { TextArea } = Input;
const ConversationInit: React.FC = ({ writingTypeModel, dispatch }) => {
  const [loading, setLoading] = useState(false);
  const [initLogs, setInitLogs] = useState<CommandType[]>([]); //对话列表 类型type = guide,lookTip,demo,userCommand,systemTip,systemPoints,docNum 不同类型渲染不同div
  const [genIsStart, setGenIsStart] = useState(false); //开始生成的状态
  const [sendIsForm, setSendIsForm] = useState(false); //底部是表单or段落
  const [bottomForm, setBottomForm] = useState([]); //底部表单
  const [commandConStyle, setCommandConStyle] = useState({}); //在输入框是表单时 动态计算commandCon的min-height 防止不满一屏
  const writingSessionId = useRef(); //页面上的writingSessionId
  const commandSendRef: any = useRef(null);
  const articlesNum = useRef(9);
  const [ipt, setIpt] = useState(''); //底部段落
  const [clickStatus, setClickStatus] = useState(false); //是否点击过显示示例
  const [articlesNumTip, setArticlesNumTip] = useState(
    '小麦支持同时生成多篇文章，建议您多选择几篇进行生成',
  );
  const commandConRef = useRef<HTMLDivElement>(null);
  const [isClick, setIsClick] = useState<boolean>(true);
  const conversationInitWrapRef = useRef(null);
  const generalConRef = useRef(null);
  const [typeDisable, setTypeDisable] = useState(false); //座谈会禁用
  const [currentType, setCurrentType] = useState<any>(null); //座谈会禁用
  //从model中获取到docList跨组件传递的数据
  const {
    display_name, //公文类型name
    frontend_code, //公文类型对应code
    id, //公文类型id  对应/api/writing_types接口返回的id
    leading_details, //数据结构描述展示 引导语
    example_details, //示例数据
    leading_words, //引导语
    sub_writing_type_ids,
    name,
  } = writingTypeModel?.writingType;
  const typeList = writingTypeModel?.typeList || [];
  //滑动到底部
  const scrollToBottom = () => {
    if (commandConRef && commandConRef.current) {
      const container = commandConRef.current;
      const startScrollTop = container.scrollTop;
      const endScrollTop = container.scrollHeight - container.clientHeight;
      const startTime = performance.now();
      const duration = 60;
      const animateScroll = (timestamp) => {
        const elapsedTime = timestamp - startTime;
        const progress = Math.min(elapsedTime / duration, 1);
        const scrollTop = startScrollTop + (endScrollTop - startScrollTop) * progress;

        container.scrollTop = scrollTop;

        if (progress < 1) {
          requestAnimationFrame(animateScroll);
        }
      };

      requestAnimationFrame(animateScroll);
    }
  };
  //计算commandCon的min-height
  const componentCommandConStyle = () => {
    if (sendIsForm) {
      //延迟 等dom响应后再获取
      setTimeout(() => {
        let height = commandSendRef.current.offsetHeight || 0;
        setCommandConStyle({
          minHeight: `calc(100vh - ${height + 90}px)`,
        });
      }, 200);
    } else {
      //清空
      setCommandConStyle({});
    }
  };

  //监听bottomForm, sendIsForm变化 计算commandCon的min-height
  useEffect(() => {
    if (bottomForm && bottomForm.length > 0) {
      componentCommandConStyle();
    }
  }, [bottomForm, sendIsForm]);
  //跳转到公文写作对话页面
  const toConversation = (writing_session_id: any) => {
    let writingTypeId = currentType ? currentType?.id : id;
    let displayName = currentType ? currentType?.display_name : display_name;
    let frontendCode = currentType ? currentType?.frontend_code : frontend_code;
    let leadingWords = currentType ? currentType?.leading_words : leading_words;
    const query = {
      writing_session_id: writing_session_id, // 当前会话id
      writing_type_id: writingTypeId, //公文类型id
      type_name: displayName,
      frontend_code: frontendCode,
      leading_words: leadingWords,
    };

    const queryStr = stringify(query);
    history.push({
      pathname: `/conversation?${queryStr}`,
    });
    console.log(loading);
  };

  //底部输入框 段落的发送
  const sectionSend = async () => {
    setLoading(true);
    const systemTip1 = {
      key: nanoid(),
      type: 'systemTip',
      data: '小麦正在根据您输入的文章提要内容，提炼出对应的信息',
    };
    setInitLogs((prev) => [...prev, systemTip1]);
    let writingTypeId = currentType ? currentType?.id : id;
    let params: any = {
      user_input: ipt,
      writing_type_id: writingTypeId,
      articles_total: articlesNum.current,
    };
    //调用提炼要点接口
    const res = await extractKeyPoints(params);
    if (res.code === 0) {
      //如果没有systemTip 则添加
      if (!initLogs.some((item) => item.type === 'systemTip')) {
        const systemTip = {
          key: nanoid(),
          type: 'systemTip',
          data: '请确认关键信息是否准确，可以点击【编辑】修改',
        };
        setTimeout(() => {
          //从initLogs里删除robotLoading
          // setInitLogs((prev) => prev.filter((item) => item.type !== 'robotLoading'));
          setLoading(false);
          setInitLogs((prev) => [...prev, systemTip]);
          setTimeout(() => {
            scrollToBottom();
          }, 100);
        }, 1500);
      }
      writingSessionId.current = res?.data?.writing_session_id;
      let key_points = cloneDeep(res?.data?.key_points || []);
      const systemPoints = {
        key: nanoid(),
        type: 'systemPoints',
        data: key_points.map((item) => {
          return {
            key: nanoid(),
            ...item,
          };
        }),
      };
      const selectNum = {
        key: nanoid(),
        type: 'selectNum',
      };
      //延迟1秒后出现systemPoints 让用户有对话感
      setTimeout(() => {
        setInitLogs((prev) => [...prev, systemPoints]);
        setTimeout(() => {
          scrollToBottom();
        }, 100);
      }, 3000);
      //延迟1秒出现selectNum 让用户有对话感
      setTimeout(() => {
        setInitLogs((prev) => [...prev, selectNum]);
        setTimeout(() => {
          scrollToBottom();
        }, 100);
        setGenIsStart(true);
        setIsClick(true);
      }, 5000);
    }
    setLoading(false);
  };
  //表单发送
  const formSend = async () => {
    setIsClick(false);
    const pointsList = cloneDeep(bottomForm);
    //先判断writingSessionId 如果不存在先调用extractKeyPoints接口获得writingSessionId
    // if (!writingSessionId.current) {
    let writingTypeId = currentType ? currentType?.id : id;
    //将pointsList的title和content 拼接成字符串
    let userInput = pointsList.map((item: any) => `${item?.title}:${item?.content},`);
    let params: any = {
      user_input: userInput.join(''),
      writing_type_id: writingTypeId,
      articles_total: articlesNum.current,
      skip_key_point: 0, //1是跳过用户输入 先生成sessionId 然后再调用structuring_write接口来更新数据
    };
    setLoading(true);
    //调用提炼要点接口
    const res = await extractKeyPoints(params);
    if (res.code === 0) {
      setLoading(false);
      writingSessionId.current = res?.data?.writing_session_id;
      let bForm = {
        key: nanoid(),
        type: 'systemPoints',
        data: res?.data?.key_points.map((item: any) => {
          item.key = nanoid();
          return item;
        }),
      };
      setInitLogs((prev) => [...prev, bForm]);
    }
    // }
    setIsClick(true);
    const selectNum = {
      key: nanoid(),
      type: 'selectNum',
    };
    setTimeout(() => {
      scrollToBottom();
    }, 100);
    setTimeout(() => {
      setInitLogs((prev) => [...prev, selectNum]);
      setTimeout(() => {
        scrollToBottom();
      }, 100);
      setGenIsStart(true);
    }, 1000);
  };
  //发送按钮
  const onSend = async () => {
    //发送的是表单
    if (sendIsForm) {
      formSend();
    } else {
      if (ipt.length === 0) {
        message.warning('请输入你的指令');
        return;
      }
      setIsClick(false);
      //发送的是段落
      //添加用户指令
      const userCommand = {
        key: nanoid(),
        type: 'userCommand',
        data: ipt,
      };
      //添加机器人等待
      // const robotLoad = {
      //   key: nanoid(),
      //   type: 'robotLoading'
      // };
      setInitLogs((prev) => [...prev, userCommand]);
      setTimeout(() => {
        scrollToBottom();
      }, 100);
      sectionSend();
    }
    //清空输入框
    setIpt('');
  };
  const onSubmit = async () => {
    //用正则判断文章篇数是不是符合1-99的整数
    if (!/^(?!0)[1-9][0-9]?$/.test(articlesNum.current)) {
      message.open({
        type: 'info',
        content: '文章篇数为1-99之间的整数',
      });
      return;
    }
    let pointsData = generalConRef?.current?.getPoints();
    setLoading(true);
    setIsClick(false);
    //跳转前 调用一遍结构化推理 开始生成文章
    let points = initLogs.find((item) => item.type === 'systemPoints')?.data;
    //如果要点框里的是编辑状态 取未确定的数据 否则取确定的数据
    const pointsList = !pointsData.edit ? cloneDeep(points) : cloneDeep(pointsData?.pointsList);
    let writingTypeId = currentType ? currentType?.id : id;
    const params2 = {
      writing_type_id: writingTypeId,
      articles_total: articlesNum.current,
      writing_session_id: writingSessionId.current,
      key_points: pointsList.map((item: CommandType) => {
        delete item.anchorName;
        delete item.anchor;
        delete item.key;
        return item;
      }),
      click_status: clickStatus ? 'clicked' : 'not_clicked',
    };
    const res2 = await structuringWrite(params2);
    if (res2.code === 0) {
      setLoading(false);
      setIsClick(true);
      toConversation(writingSessionId.current);
    }
  };

  //公文篇数
  const handleChange = (val: any) => {
    if (/^(?!0)[1-9][0-9]?$/.test(val)) {
      articlesNum.current = val;
      let seconds = 0;
      if (val < 10) {
        setArticlesNumTip(`小麦支持同时生成多篇文章，建议您多选择几篇进行生成`);
      } else if (val > 30) {
        setArticlesNumTip(`小麦预计耗时较长，您可以先处理其他事务，稍后查看`);
      } else {
        seconds = val * 5; // 1 对应 5 秒
        const minutes = Math.ceil(seconds / 60);
        setArticlesNumTip(`小麦将全力加速生成您的文章，预计耗时 ${minutes} 分钟`);
      }
    }
  };
  //输入框 切换表单or段落
  const toggleForm = () => {
    setSendIsForm(!sendIsForm);
    componentCommandConStyle();
    //滑动到底部
    if (conversationInitWrapRef.current && !sendIsForm) {
      setTimeout(() => {
        conversationInitWrapRef.current.scrollTop =
          conversationInitWrapRef?.current?.scrollHeight || 0;
      }, 100);
    }
  };
  //切换回输入框模式 切换回输入框时 将要点框删除 等下次点击发送再次生成
  const toggleStartGen = () => {
    //从initLogs里删除systemPoints和selectNum
    setInitLogs((prev) => prev.filter((item) => item.type !== 'systemPoints'));
    setInitLogs((prev) => prev.filter((item) => item.type !== 'selectNum'));
    setInitLogs((prev) => prev.filter((item) => item.type !== 'systemTip'));
    setGenIsStart(false);
  };

  //点击查询示例的时候 在initLogs里添加示例 假如已存在示例 不添加
  const addDemo = () => {
    let exampleDetails = currentType ? currentType?.example_details : example_details;
    //如果initLogs里已存在demo 则不添加
    let isHasDemo = initLogs.filter((item) => item.type === 'demo1').length > 0 ? true : false;
    if (!isHasDemo) {
      const example1 = {
        key: nanoid(),
        type: 'demo1',
        data: exampleDetails,
      };
      const example2 = {
        key: nanoid(),
        type: 'demo2',
        data: exampleDetails,
      };
      setInitLogs((prev) => [...prev, example1]);
      setTimeout(() => {
        setInitLogs((prev) => [...prev, example2]);
      }, 1000);
      setTimeout(() => {
        setClickStatus(true);
        scrollToBottom();
      }, 1100);
    }
  };

  //页面初始化
  useEffect(() => {
    //修改标题
    dispatch({
      type: 'headerModel/changeTitle',
      payload: display_name,
    });

    //根据writingTypeModel带来的leading_details和example_details 添加引导语和示例
    let guide1: any = {
      key: nanoid(),
      type: 'guide1',
      data: leading_details,
    };
    //添加第一条 = 引导语
    setTimeout(() => {
      setInitLogs([guide1]);
    }, 1000);
    //如果不是座谈会的
    if (
      sub_writing_type_ids &&
      sub_writing_type_ids.length === 1 &&
      sub_writing_type_ids[0] === id
    ) {
      let guide2: any = {
        key: nanoid(),
        type: 'guide2',
        data: leading_details,
      };
      let guide3: any = {
        key: nanoid(),
        type: 'guide3',
        data: leading_details,
      };

      setTimeout(() => {
        setInitLogs((prev: any) => [...prev, guide2]);
      }, 2000);
      setTimeout(() => {
        setInitLogs((prev: any) => [...prev, guide3]);
      }, 3000);

      //添加第二条 1秒后添加查看示例
      setTimeout(() => {
        let lookTip = {
          key: nanoid(),
          type: 'lookTip',
        };
        setInitLogs((prev) => [...prev, lookTip]);
      }, 4000);

      //将example_details的content清空 拷贝到底部表单bottomForm里
      let key_points = example_details?.key_points || [];
      let bottomForm = cloneDeep(key_points);
      for (let point of bottomForm) {
        point.key = nanoid(); // 生成唯一key
        point.content = ''; // 清空content字段
      }
      setBottomForm(bottomForm);
    } else {
      setIsClick(false);
      let newLeading = cloneDeep(leading_details);
      let colloquiaList = typeList.filter(
        (item: any) => sub_writing_type_ids?.indexOf(item.id) >= 0,
      );
      colloquiaList.forEach((item: any) => {
        item.showName = item.display_name.replace('座谈会_', '');
      });
      newLeading.display_name = name;
      let guide2: any = {
        key: nanoid(),
        type: 'guide2',
        data: newLeading,
      };
      let guide4: any = {
        key: nanoid(),
        type: 'guide4',
        data: colloquiaList,
      };
      setTimeout(() => {
        setInitLogs((prev: any) => [...prev, guide2]);
      }, 2000);
      setTimeout(() => {
        setInitLogs((prev: any) => [...prev, guide4]);
      }, 3000);
    }
  }, []);
  //更新updataPoints
  const updataPoints = (data: any) => {
    //更新systemPoints里的data
    // let points = initLogs.find((item) => item.type === 'systemPoints')?.data;
    console.log(initLogs);
    setInitLogs((prev: any) => {
      return prev.map((item: any) => {
        if (item.type === 'systemPoints') {
          item.data = data;
        }
        return item;
      });
    });
  };
  //选择座谈会类型
  const handleSelectColloquia = (item: any) => {
    setTypeDisable(true);
    setCurrentType(item);
    let guide3: any = {
      key: nanoid(),
      type: 'guide3',
      data: item.leading_details,
    };
    setInitLogs((prev: any) => [...prev, guide3]);
    //添加第二条 1秒后添加查看示例
    setTimeout(() => {
      let lookTip = {
        key: nanoid(),
        type: 'lookTip',
      };
      setInitLogs((prev) => [...prev, lookTip]);
    }, 1000);
    //将example_details的content清空 拷贝到底部表单bottomForm里
    let key_points = item.example_details?.key_points || [];
    let bottomForm = cloneDeep(key_points);
    for (let point of bottomForm) {
      point.key = nanoid(); // 生成唯一key
      point.content = ''; // 清空content字段
    }
    setBottomForm(bottomForm);
    setIsClick(true);
  };
  return (
    <div
      ref={conversationInitWrapRef}
      className={`conversationInitWrap ${
        sendIsForm ? (bottomForm.length > 1 ? 'bottomLong' : 'bottomShort') : ''
      } ${genIsStart ? 'bottomNo' : ''}`}
    >
      <div className="conversationInitBox">
        <div className="conversationInitTitle">写作实习生 - 小麦</div>

        {/* {loading ? (
          <div className="loadingBox">
            <img src={GENE_LOADING} alt="" height={33} width={55} style={{ marginRight: 4 }} />
          </div>
        ) : (
          <></>
        )} */}
        {genIsStart ? (
          <div className="returnBtn">
            <Button
              shape="circle"
              icon={<LeftOutlined />}
              onClick={() => {
                toggleStartGen();
              }}
            />
          </div>
        ) : (
          <></>
        )}

        <div className="commandCon" ref={commandConRef} style={commandConStyle}>
          {initLogs.length > 0 &&
            initLogs.map((item) => {
              if (item.type === 'robotLoading') {
                return (
                  <div className="commandList" key={item.key}>
                    <div className="commandList-hd">
                      <img className="avatar" src={ROBOT_AVATAR} height={42} width={40} />
                    </div>
                    <div className="commandList-bd">
                      <img className="avatar" src={POINTLOADING} height={14} width={21} />
                    </div>
                  </div>
                );
              } else if (item.type === 'guide1') {
                return (
                  <Guide
                    key={item.key}
                    type="guide1"
                    leading_details={leading_details}
                    data={item.data}
                  ></Guide>
                );
              } else if (item.type === 'guide2') {
                return (
                  <Guide
                    key={item.key}
                    type="guide2"
                    leading_details={leading_details}
                    data={item.data}
                  ></Guide>
                );
              } else if (item.type === 'guide3') {
                return (
                  <Guide
                    key={item.key}
                    type="guide3"
                    leading_details={leading_details}
                    data={item.data}
                  ></Guide>
                );
              } else if (item.type === 'guide4') {
                return (
                  <div className="commandList" key={nanoid()}>
                    <div className="commandList-hd">
                      <img className="avatar" src={ROBOT_AVATAR} height={42} width={40} />
                    </div>
                    <div className="writingSelect">
                      <div className="writingSelectTitle">请选择需要座谈会的使用场景：</div>
                      <div className="writingSelectList">
                        {item.data.map((item2: any) => {
                          return (
                            <span
                              key={nanoid()}
                              className={typeDisable ? 'typeDisable' : ''}
                              onClick={() => {
                                handleSelectColloquia(item2);
                              }}
                            >
                              {item2.showName}
                            </span>
                          );
                        })}
                      </div>
                    </div>
                  </div>
                );
              } else if (item.type === 'lookTip') {
                return <LookTip key={item.key} addDemo={addDemo}></LookTip>;
              } else if (item.type === 'demo1') {
                return <Demo key={item.key} type={item.type} data={item.data}></Demo>;
              } else if (item.type === 'demo2') {
                return <Demo key={item.key} type={item.type} data={item.data}></Demo>;
              } else if (item.type === 'userCommand') {
                return (
                  <div className="commandList userCommand" key={item.key}>
                    <div
                      className="commandList-bd"
                      dangerouslySetInnerHTML={{ __html: replaceN(item.data) }}
                    ></div>
                    <div className="commandList-hd">
                      <img className="avatar" src={USER_AVATAR} height={42} width={40} />
                    </div>
                  </div>
                );
              } else if (item.type === 'systemTip') {
                return (
                  <div className="commandList" key={item.key}>
                    <div className="commandList-hd">
                      <img className="avatar" src={ROBOT_AVATAR} height={42} width={40} />
                    </div>
                    <div className="commandList-bd">{item.data}</div>
                  </div>
                );
              } else if (item.type === 'systemPoints') {
                return (
                  <div className="generalBox" key={item.key}>
                    <General
                      ref={generalConRef}
                      data={item?.data}
                      updataPoints={updataPoints}
                    ></General>
                  </div>
                );
              } else if (item.type === 'selectNum') {
                return (
                  <SelectNum
                    key={item.key}
                    articlesNum={articlesNum}
                    articlesNumTip={articlesNumTip}
                    handleChange={handleChange}
                  ></SelectNum>
                );
              } else {
                return <></>;
              }
            })}
        </div>
        {genIsStart ? (
          <></>
        ) : (
          <div className="commandSend" ref={commandSendRef}>
            <div className="sendTypeTogg">
              <span className="sendTypeTogg-hd">请输入文章提要内容</span>
              {/* 段落or表单切换 */}
              {sendIsForm ? (
                <Button
                  className="sendTypeTogg-bd"
                  onClick={() => {
                    toggleForm();
                  }}
                  disabled={!isClick}
                >
                  段落样式填写
                </Button>
              ) : (
                <Button
                  className="sendTypeTogg-bd"
                  disabled={!isClick}
                  onClick={() => {
                    toggleForm();
                  }}
                >
                  表单样式填写
                </Button>
              )}
            </div>
            <div className="sendConBox">
              {sendIsForm ? (
                <General
                  isBottomForm={true}
                  data={bottomForm}
                  setBottomForm={setBottomForm}
                ></General>
              ) : (
                <TextArea
                  value={ipt}
                  onChange={(e) => setIpt(e.target.value)}
                  placeholder="请参照示例输入相关信息，信息越丰富，生成文章的质量越高"
                  autoSize={{ minRows: 5, maxRows: 5 }}
                />
              )}
            </div>
            <div className="submitBox">
              <Button type="primary" onClick={() => onSend()} disabled={!isClick}>
                发送
              </Button>
            </div>
          </div>
        )}
      </div>
      {genIsStart ? (
        <div className="startGenerateBox">
          <Button type="primary" onClick={() => onSubmit()} disabled={!isClick}>
            开始生成
          </Button>
        </div>
      ) : (
        <></>
      )}
    </div>
  );
};

// export default ConversationInit;
export default connect(({ writingTypeModel, headerModel }) => ({ writingTypeModel, headerModel }))(
  ConversationInit,
);
